Skip to content

fix(ts): expose open/openSync/openRemote for NodeNext#324

Merged
ospfranco merged 2 commits into
OP-Engineering:mainfrom
effect-native:feat/ts-explicit-reexports-embedded-alias
Sep 15, 2025
Merged

fix(ts): expose open/openSync/openRemote for NodeNext#324
ospfranco merged 2 commits into
OP-Engineering:mainfrom
effect-native:feat/ts-explicit-reexports-embedded-alias

Conversation

@subtleGradient

@subtleGradient subtleGradient commented Sep 12, 2025

Copy link
Copy Markdown
Contributor

fix(ts): expose open/openSync/openRemote for NodeNext

Problem

  • In projects using moduleResolution: NodeNext, @op-engineering/op-sqlite namespace and named imports do not expose value exports from ./functions (e.g., open, openSync, openRemote). This produces type errors despite those functions existing at runtime.

Symptoms

// consumer tsconfig: { "module": "NodeNext", "moduleResolution": "NodeNext" }
import * as Sqlite from '@op-engineering/op-sqlite';
Sqlite.open({ name: 'test.db' });
// TS2339: Property 'open' does not exist on type 'typeof import(".../op-sqlite/lib/typescript/src/index")'.

import { open } from '@op-engineering/op-sqlite';
// TS2305: Module '"@op-engineering/op-sqlite"' has no exported member 'open'.

Goal

  • Ensure open, openSync, and openRemote are visible from the package root in TypeScript projects using moduleResolution: NodeNext (common in RN/modern ESM), so both namespace and named imports type-check.

Blocker

  • Under NodeNext, TypeScript can elide star re-exports that originate from internal subpaths not listed in the package exports map. Our index.d.ts used:
    • export * from './functions'
    • export { Storage } from './Storage'
    • export * from './types'
  • Result: the namespace import’s type shape omitted value exports from ./functions (e.g., open/openSync/openRemote), while direct exports like Storage still appeared. Runtime ESM was fine; this was a type visibility issue only.

Options

  • Option A (minimal): Replace export * with explicit named re-exports in src/index.ts so TypeScript emits concrete named re-exports in index.d.ts.
  • Option B (defense-in-depth): Add subpath entries in package.json#exports for ./functions, ./types, and ./Storage to help NodeNext resolvers “see” those modules explicitly across TS versions.
  • Option C (naming follow-up): Address the isIOSEmbeeded vs isIOSEmbedded spelling mismatch without breaking changes by providing a correctly spelled export alongside a deprecated alias.

Solution

  • Implemented Option A:
    • Values: src/index.ts now re-exports explicitly: OPSQLite, open, openRemote, openSync, moveAssetsDatabase, getDylibPath, isSQLCipher, isLibsql, isIOSEmbedded, and isIOSEmbeeded.
    • Types: replaced export * from './types' with export type { ... } from './types' listing all public types to avoid NodeNext elision and ensure types are visible to both namespace and named imports.
  • Implemented Option C: Added correctly spelled isIOSEmbedded and kept isIOSEmbeeded as a @deprecated alias for backward compatibility.
  • Left Option B out of scope for now; can be added later if needed.

Verification

  • yarn typecheck passes; yarn prepare regenerates types with named re-exports.
  • In a NodeNext consumer:
    • import * as Sqlite from '@op-engineering/op-sqlite' then Sqlite.open({ name: 'test.db' }) type-checks.
    • import { open } from '@op-engineering/op-sqlite' also type-checks.

Notes

  • No runtime behavior changed; this only affects type visibility. The deprecated alias keeps existing consumers working while nudging toward the correct spelling.

Related: Effect-TS/effect#5499 effect-native/effect-native#122

Copilot AI review requested due to automatic review settings September 12, 2025 17:42

This comment was marked as spam.

@ospfranco

Copy link
Copy Markdown
Contributor

Your usage of NodeNext already brought other changes just to make your use-case work... it's getting to the annoying point. I will merge this but on the first pebble I find, I might revert this and just use Bundler as that is the value pure RN/Expo projects use.

@ospfranco ospfranco merged commit 3c8703a into OP-Engineering:main Sep 15, 2025
8 checks passed
@subtleGradient subtleGradient deleted the feat/ts-explicit-reexports-embedded-alias branch September 16, 2025 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants